package com.jy.oms.framework.asyn.task.log.database;

import com.alibaba.fastjson.JSON;
import com.jy.oms.framework.asyn.task.constants.TaskConstants;
import com.jy.oms.framework.asyn.task.constants.TaskStateEnum;
import com.jy.oms.framework.asyn.task.core.ExecutorConfig;
import com.jy.oms.framework.asyn.task.core.ExecutorContext;
import com.jy.oms.framework.asyn.task.core.TaskIdCreateService;
import com.jy.oms.framework.asyn.task.log.ITaskLogService;
import com.jy.oms.framework.asyn.task.log.bo.QueryTaskLogBo;
import com.jy.oms.framework.asyn.task.log.bo.QueryTaskLogResultBo;
import com.jy.oms.framework.asyn.task.log.database.dao.SysTaskLogDao;
import com.jy.oms.framework.asyn.task.log.database.entity.SysTaskLog;
import com.jy.oms.framework.asyn.task.model.TaskDto;
import com.jy.oms.framework.asyn.task.model.TaskLogDto;
import com.jy.oms.framework.asyn.task.model.TaskResultDto;
import com.jy.oms.framework.asyn.task.model.TaskWrapper;
import com.jy.oms.framework.asyn.task.util.TaskCommonThreadPool;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * db任务日志服务
 *
 * @author liuquan
 */
@Service
public class TaskDbLogService implements ITaskLogService {
    private static Logger logger = LoggerFactory.getLogger(TaskDbLogService.class);
    @Autowired
    private TaskIdCreateService idCreateService;
    @Autowired
    private SysTaskLogDao sysTaskLogDao;

    @Override
    public void insert(TaskResultDto taskResultDto) {
        try {
            sysTaskLogDao.insertSysTaskLog(this.convert(taskResultDto));
        } catch (Exception e){
            logger.error("添加日志报错, {}", JSON.toJSONString(taskResultDto), e);
        }
    }

    private SysTaskLog convert(TaskResultDto taskResultDto) {
        ExecutorConfig executorConfig = ExecutorContext.getExecutorConfig();
        TaskWrapper taskWrapper = taskResultDto.getTaskWrapper();
        TaskDto taskDto = taskWrapper.getTaskDto();
        SysTaskLog sysTaskLog = new SysTaskLog();
        sysTaskLog.setId(idCreateService.getId());
        sysTaskLog.setBusinessGroup(executorConfig.getBusinessGroup());
        sysTaskLog.setTaskCode(taskDto.getTaskCode());
        if (taskDto.getParam() instanceof String) {
            sysTaskLog.setTaskParam((String) taskDto.getParam());
        } else {
            sysTaskLog.setTaskParam(JSON.toJSONString(taskDto.getParam()));
        }
        sysTaskLog.setBillCode(taskDto.getBillCode());
        sysTaskLog.setState(taskResultDto.getTaskState().getCode());
        sysTaskLog.setResponse(taskResultDto.getResponse());
        sysTaskLog.setCallCount(taskResultDto.getCallCount());
        sysTaskLog.setCostTime(taskResultDto.getCostTime());
        sysTaskLog.setCallbackState(taskResultDto.getCallbackState() != null
                ? taskResultDto.getCallbackState().getCode() : TaskStateEnum.UNDO.getCode());
        sysTaskLog.setCallbackCostTime(taskResultDto.getCallbackCostTime());
        sysTaskLog.setEnvFlag(executorConfig.getEnv());
        sysTaskLog.setTaskCreateTime(new Date());
        sysTaskLog.setCheckerCostTime(taskResultDto.getCheckerCostTime());
        sysTaskLog.setUuid(taskWrapper.getParamIdentifier());
        sysTaskLog.setCreateDate(new Date());
        sysTaskLog.setCreateBy(StringUtils.defaultIfBlank(taskDto.getCreator(), "system"));
        return sysTaskLog;
    }

    @Override
    public void insert(List<TaskResultDto> taskResultList) {
        try {
            List<SysTaskLog> sysTaskLogList = taskResultList.stream().map(this::convert).collect(Collectors.toList());
            sysTaskLogDao.insertSysTaskLogList(sysTaskLogList);
        } catch (Exception e){
            logger.error("添加日志报错, {}", JSON.toJSONString(taskResultList), e);
        }
    }

    @Override
    public void insert(TaskLogDto taskLogDto) {
        try {
            ExecutorConfig executorConfig = ExecutorContext.getExecutorConfig();
            SysTaskLog sysTaskLog = new SysTaskLog();
            sysTaskLog.setId(idCreateService.getId());
            sysTaskLog.setBusinessGroup(executorConfig.getBusinessGroup());
            sysTaskLog.setTaskCode(taskLogDto.getTaskCode());
            if (taskLogDto.getParam() != null) {
                if (taskLogDto.getParam() instanceof String) {
                    sysTaskLog.setTaskParam((String) taskLogDto.getParam());
                } else {
                    sysTaskLog.setTaskParam(JSON.toJSONString(taskLogDto.getParam()));
                }
            }
            sysTaskLog.setBillCode(taskLogDto.getBillCode());
            if (taskLogDto.getTaskState() != null) {
                sysTaskLog.setState(taskLogDto.getTaskState().getCode());
            } else {
                sysTaskLog.setState(TaskStateEnum.DONE.getCode());
            }
            if (taskLogDto.getResponse() != null) {
                if (taskLogDto.getResponse() instanceof String) {
                    String response = (String) taskLogDto.getResponse();
                    sysTaskLog.setResponse(response.length() > TaskConstants.TASK_FAIL_RES_MESSAGE_LIMIT ? response.substring(0, TaskConstants.TASK_FAIL_RES_MESSAGE_LIMIT) : response);
                } else {
                    sysTaskLog.setResponse(JSON.toJSONString(taskLogDto.getResponse()));
                }
            }
            sysTaskLog.setCallCount(1);
            sysTaskLog.setCostTime(taskLogDto.getCostTime());
            sysTaskLog.setCallbackState(TaskStateEnum.UNDO.getCode());
            sysTaskLog.setCallbackCostTime(0);
            sysTaskLog.setEnvFlag(executorConfig.getEnv());
            sysTaskLog.setTaskCreateTime(new Date());
            sysTaskLog.setCheckerCostTime(0);
            sysTaskLog.setCreateDate(new Date());
            sysTaskLog.setCreateBy("system");
            sysTaskLogDao.insertSysTaskLog(sysTaskLog);
        } catch (Exception e){
            logger.error("添加日志报错, {}", JSON.toJSONString(taskLogDto), e);
        }
    }

    @Override
    public void insertAsync(TaskLogDto taskLogDto) {
        TaskCommonThreadPool.getInstance().execute(() -> {
            this.insert(taskLogDto);
        });
    }

    @Override
    public List<QueryTaskLogResultBo> queryLog(QueryTaskLogBo taskLogQueryDto) {
        ExecutorConfig executorConfig = ExecutorContext.getExecutorConfig();
        taskLogQueryDto.setBusinessGroup(executorConfig.getBusinessGroup());
        taskLogQueryDto.setEnvFlag(executorConfig.getEnv());

        List<SysTaskLog> sysTaskLogs = this.sysTaskLogDao.querySysTaskLog(taskLogQueryDto);
        if (CollectionUtils.isEmpty(sysTaskLogs)) {
            return Collections.emptyList();
        }

        return sysTaskLogs.stream().map(item -> {
            QueryTaskLogResultBo resultBo = new QueryTaskLogResultBo();
            resultBo.setTaskCode(item.getTaskCode());
            resultBo.setTaskParam(item.getTaskParam());
            resultBo.setCreateDate(item.getCreateDate());
            return resultBo;
        }).collect(Collectors.toList());
    }
}
